package com.fingard.dsp.bank.directbank.czb02;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IContract;
import com.fingard.dsp.bank.reqrespobj.contract.*;
import com.fingard.dsp.bank.reqrespobj.contract.detail.RetAtsContractDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Date;

/**
 * 浙商银行代收协议签约
 * <p>
 * 参考文档：浙商银行收付通接口规范（代收）.doc
 *
 * @author FanH
 * @date 2019/9/12
 */
public class CZB02Contract extends CZB02Base implements IContract {

    /**
     * 开发接口：
     * 1. 3.3.3.8	发送短信验证码[0008]
     * 2. 3.3.3.1	代收协议签约[0001]
     */
    @Override
    public RetAtsContract contract(ReqContract p_req) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_req.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_req.contractDetail.askNumber;
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req.contractDetail.recAct, "contract");
            if (actItem != null) {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                StringBuilder reqMsg = new StringBuilder();
                if ("01".equals(p_req.contractDetail.step)) {
                    CZB02Header bankHeader = new CZB02Header();
                    bankHeader.transCode = "0008";
                    bankHeader.reqSeqNo = p_req.contractDetail.askNumber;

                    writeCommonHeader(xmlWriter, actItem, bankHeader);
                    xmlWriter.writeStartElement("body");
                    xmlWriter.writeElementString("xyh", p_req.contractDetail.payAct);//协议号
                    reqMsg.append("<xyh>" + p_req.contractDetail.payAct + "</xyh>");//协议号

                    xmlWriter.writeElementString("sjh", p_req.contractDetail.cellPhone);//手机号
                    reqMsg.append("<sjh>" + p_req.contractDetail.cellPhone + "</sjh>");//手机号


                    //短信类型(0签约，1支付，2四要素扣款支付)
                    String smsType = getBankConfig().getValueAsString("smsType");
                    if (StringHelper.hasAnyChar(smsType)) {
                        xmlWriter.writeElementString("dxlx", smsType);//短信类型
                        reqMsg.append("<dxlx>" + smsType + "</dxlx>");//短信类型
                    }
                    if ("0".equals(smsType) || "2".equals(smsType)) {
                        xmlWriter.writeElementString("fkzhm", p_req.contractDetail.payName);//付款账户名
                        reqMsg.append("<fkzhm>" + p_req.contractDetail.payName + "</fkzhm>");//付款账户名

                        xmlWriter.writeElementString("fkzh", p_req.contractDetail.payAct);//付款账户
                        reqMsg.append("<fkzh>" + p_req.contractDetail.payAct + "</fkzh>");//付款账户

                        if ("0".equals(smsType)) {
                            xmlWriter.writeElementString("sfzh", p_req.contractDetail.certNum);//身份证号
                            reqMsg.append("<sfzh>" + p_req.contractDetail.certNum + "</sfzh>");//身份证号

                            xmlWriter.writeElementString("fkzhlb", "0");//付款账号类别
                            reqMsg.append("<fkzhlb>0</fkzhlb>");//付款账号类别
                        }
                    }
                } else if ("02".equals(p_req.contractDetail.step)) {
                    CZB02Header bankHeader = new CZB02Header();
                    bankHeader.transCode = "0001";
                    bankHeader.reqSeqNo = p_req.contractDetail.askNumber;

                    writeCommonHeader(xmlWriter, actItem, bankHeader);
                    xmlWriter.writeStartElement("body");
                    xmlWriter.writeElementString("xyh", p_req.contractDetail.payAct);//协议号
                    reqMsg.append("<xyh>" + p_req.contractDetail.payAct + "</xyh>");//协议号

                    xmlWriter.writeElementString("fkzh", p_req.contractDetail.payAct);//付款账号
                    reqMsg.append("<fkzh>" + p_req.contractDetail.payAct + "</fkzh>");//付款账号

                    xmlWriter.writeElementString("fkzhm", p_req.contractDetail.payName);//付款账户名
                    reqMsg.append("<fkzhm>" + p_req.contractDetail.payName + "</fkzhm>");//付款账户名

                    xmlWriter.writeElementString("ylyhsjh", p_req.contractDetail.cellPhone);//预留银行手机号
                    reqMsg.append("<ylyhsjh>" + p_req.contractDetail.cellPhone + "</ylyhsjh>");//预留银行手机号

                    xmlWriter.writeElementString("sfzh", p_req.contractDetail.certNum);//身份证号
                    reqMsg.append("<sfzh>" + p_req.contractDetail.certNum + "</sfzh>");//身份证号

                    // 账户类型   0 - 对私； 1 - 对公；
                    xmlWriter.writeElementString("fkzhlb", "0");//付款账号类别
                    reqMsg.append("<fkzhlb>0</fkzhlb>");//付款账号类别

                    String singleLimit = p_req.contractDetail.singleLimit;
                    if (StringHelper.isNullOrEmpty(singleLimit)) {
                        singleLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "singleLimit");
                        if (StringHelper.isNullOrEmpty(singleLimit)) {
                            singleLimit = "0.00";
                        }
                    }
                    xmlWriter.writeElementString("dbkkxe", singleLimit);//单笔扣款限额
                    reqMsg.append("<dbkkxe>" + singleLimit + "</dbkkxe>");//单笔扣款限额

                    String dayAmtLimit = p_req.contractDetail.dayAmtLimit;
                    if (StringHelper.isNullOrEmpty(dayAmtLimit)) {
                        dayAmtLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "dayAmtLimit");
                        if (StringHelper.isNullOrEmpty(dayAmtLimit)) {
                            dayAmtLimit = "0.00";
                        }
                    }
                    xmlWriter.writeElementString("rljkkxe", dayAmtLimit);//日累计扣款限额
                    reqMsg.append("<rljkkxe>" + dayAmtLimit + "</rljkkxe>");//日累计扣款限额

                    String monthAmtLimit = p_req.contractDetail.monthAmtLimit;
                    if (StringHelper.isNullOrEmpty(monthAmtLimit)) {
                        monthAmtLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "monthAmtLimit");
                        if (StringHelper.isNullOrEmpty(monthAmtLimit)) {
                            monthAmtLimit = "0.00";
                        }
                    }
                    xmlWriter.writeElementString("zljkkxe", monthAmtLimit);//总累计扣款限额
                    reqMsg.append("<zljkkxe>" + monthAmtLimit + "</zljkkxe>");//总累计扣款限额

                    xmlWriter.writeElementString("dksxrq", Format.Date8Format.format(new Date()));//代收生效日期
                    reqMsg.append("<dksxrq>" + Format.Date8Format.format(new Date()) + "</dksxrq>");//代收生效日期

                    String deadLine = p_req.contractDetail.deadLine;
                    if (StringHelper.isNullOrEmpty(deadLine)) {
                        deadLine = getBankConfig().getMapValueByKey("contractKeyMapping", "deadLine");
                        if (StringHelper.isNullOrEmpty(deadLine)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "缺失配置节点'deadLine'或值为空!";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                    }
                    xmlWriter.writeElementString("dkzzrq", deadLine);//代收终止日期
                    reqMsg.append("<dkzzrq>" + deadLine + "</dkzzrq>");//代收终止日期


                    String smsCode = p_req.contractDetail.smsCode;
                    if (!"".equals(smsCode) && smsCode != null) {
                        xmlWriter.writeElementString("dxyzm", smsCode);//短信验证码
                        reqMsg.append("<dxyzm>" + smsCode + "</dxyzm>");//短信验证码
                    }

                    String token = p_req.contractDetail.token;
                    if (!"".equals(token) && token != null) {
                        xmlWriter.writeElementString("yzmxh", token);//验证码序号
                        reqMsg.append("<yzmxh>" + token + "</yzmxh>");//验证码序号
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "未能识别的step：" + p_req.contractDetail.step;
                    retAts.writeRetDetail(tmpRetDetail);
                    return retAts;
                }

                xmlWriter.writeEndDocument();

                String signMsg = signData(reqMsg.toString(), actItem);
                WriteBankLogLn2("签名原始数据:\r\n" + reqMsg.toString());

                String reqData = xmlWriter.toXmlString().replaceAll("<bz1 />", "<bz1>" + signMsg + "</bz1>");

                String[] tmpRetStr = sendToBank(reqData);

                if (tmpRetStr[0].length() == 0) {
                    WriteBankLogStep3(tmpRetStr[1]);

                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRespCode = tmpBkReader.getFirstText("/response/head/fhm");
                        if (StringHelper.hasAnyChar(tmpRespCode)) {
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/response/head/fhxx");
                            if ("000000".equals(tmpRespCode)) {
                                if ("01".equals(p_req.contractDetail.step)) {
                                    tmpRetDetail.signConfirmType = this.getBankConfig().getMapValueByKey("signConfirmMapping", p_req.contractDetail.payBankCode);
                                    tmpRetDetail.token = tmpBkReader.getFirstText("/response/body/yzmxh");
                                } else {
                                    tmpRetDetail.signState = ContractState.SUCCESS;
                                    tmpRetDetail.authCode = tmpBkReader.getFirstText("/response/body/xyh");
                                }
                            } else {
                                tmpRetDetail.signState = ContractState.FAIL;
                            }
                            tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", tmpRespCode);
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/response/head/fhxx");
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpRetStr[1];
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号[" + p_req.contractDetail.recAct + "]商户配置信息!";
            }
        } catch (Exception e) {
            WriteBankLogLn("");
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsContract upContract(ReqContract p_req) throws Exception {
        return null;
    }

    /**
     * 开发接口：
     * 1. 3.3.3.4	代收协议查询[0004]
     */
    @Override
    public RetAtsContract qryContract(ReqContract p_reqQry) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_reqQry.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_reqQry.contractDetail.askNumber;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQry.contractDetail.recAct, "contract");
            if (actItem != null) {
                CZB02Header bankHeader = new CZB02Header();
                bankHeader.transCode = "0004";
                bankHeader.reqSeqNo = p_reqQry.reqHeader.transSeqID;

                XmlTextWriter xmlWriter = new XmlTextWriter();
                StringBuilder reqMsg = new StringBuilder();

                writeCommonHeader(xmlWriter, actItem, bankHeader);
                xmlWriter.writeStartElement("body");
                xmlWriter.writeElementString("xyh", p_reqQry.contractDetail.payAct);//协议号
                reqMsg.append("<xyh>" + p_reqQry.contractDetail.payAct + "</xyh>");//协议号
                xmlWriter.writeEndDocument();

                String signMsg = signData(reqMsg.toString(), actItem);
                WriteBankLogLn2("签名原始数据:\r\n" + reqMsg.toString());

                String reqData = xmlWriter.toXmlString().replaceAll("<bz1 />", "<bz1>" + signMsg + "</bz1>");
                String[] tmpRetStr = sendToBank(reqData);

                if (tmpRetStr[0].length() == 0) {
                    WriteBankLogStep3(tmpRetStr[1]);

                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);

                    if (tmpBkReader != null) {
                        String tmpRespCode = tmpBkReader.getFirstText("/response/head/fhm");
                        if (StringHelper.hasAnyChar(tmpRespCode)) {
                            tmpRetDetail.respCode = "0";
                            String fhxx = tmpBkReader.getFirstText("/response/head/fhxx");
                            tmpRetDetail.respInfo = fhxx;
                            // 0-已签约、1-已解约、2-未签约
                            if ("交易成功".equals(fhxx)) {
                                fhxx = ContractState.SUCCESS;
                            } else {
                                fhxx = ContractState.UNSIGNED;
                            }
                            tmpRetDetail.signState = fhxx;
                            if (ContractState.SUCCESS.equals(tmpRetDetail.signState)) {
                                if (tmpBkReader.read("/response/body")) {
                                    tmpRetDetail.authCode = tmpBkReader.readedXElement.getSingleText("xyh");
                                    tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("fkzh");
                                    tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("fkzhm");
                                    tmpRetDetail.cellPhone = tmpBkReader.readedXElement.getSingleText("ylyhsjh");
                                    tmpRetDetail.certNum = tmpBkReader.readedXElement.getSingleText("sfzh");
                                    tmpRetDetail.deadLine = tmpBkReader.readedXElement.getSingleText("dkzzrq");
                                    String singleLimit = tmpBkReader.readedXElement.getSingleText("dbkkxe");
                                    if (StringHelper.hasAnyChar(singleLimit)) {
                                        tmpRetDetail.singleLimit = singleLimit;
                                    }
                                }
                            }
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/response/head/fhxx");
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpRetStr[1];
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号:[" + p_reqQry.contractDetail.recAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsQryBatContract qryBatContract(ReqQryBatContract p_reqQry) throws Exception {
        return null;
    }
}
